import { Component, ComponentType } from "./Component";
import { must, any } from "../core/logic";
import { Register } from "../register/Register";
import { ids } from "../core/ids";
/**
 * 渲染组件
 * @class
 * @extends w.component.Component
 * @memberof w.component
 */
class Mesh extends Component {
    /**
     * @constructor
     * @param {w.geometry.Geometry} opts.geometry 【必选】几何体。
     * @param {w.material.Material} opts.material 【必选】材质。
     */
    constructor(opts = {}) {
        opts.type=any(opts.type,ComponentType.Mesh);
        opts.id=ids.generate();//生成颜色id
        super(opts);
        this.geometry = must(opts.geometry);
        this.material = must(opts.material);
        this.visibility = any(opts.visibility, true);
        this._hash = '';
        this.autoUpdate=true;
        this.update();
    }
    updateState(){
        this.setState(this.geometry.getState()&&this.material.getState());
    }
    updateHash() {
        if(this.geometry && this.material) {
            this._hash = this.geometry.hash + this.material.hash;
        }
    }
    get hash() {
        return this._hash;
    }
    set geometry(v) {
        this._geometry = v;
        this._geometry.bind(this);
        this.update();
        return this;
    }

    get geometry() {
        return this._geometry;
    }

    set material(v) {
        this._material = v;
        this._material.bind(this);
        this.update();
        return this;
    }

    get material() {
        return this._material;
    }

    set visibility(v) {
        this._visibility = v;
        this.update();
        return this;
    }

    get visibility() {
        return this._visibility;
    }
    destroy(){
        let flag=super.destroy();
        this.geometry.unBind(this);
        this.material.unBind(this);
        if(flag){
            this.material.destroy();
            this.geometry.destroy();
            const meshRender=Register.instance.manager(ComponentType.MeshRender).get('x');
           let renderInfo=  meshRender.get(this.id)
            if(renderInfo){
                meshRender.remove(renderInfo);
                ids.recovery(this.id);//收回id
            }
           
        }
        return flag;
    }
    toGPU() {
        this.material.toGPU();
        //根据材质类型不同，分别写入idColor
        if(this.material.materialType=="BasicMaterial"){
            this.material.getParam('material').buffer(ids.toColor(this.id),96,);
        }else if(this.material.materialType=="StandardMaterial"){
            this.material.getParam('material').buffer(ids.toColor(this.id),64);
        }
        let {defs,config,grouplayouts2,bindGroup2,grouplayouts3,bindGroup3}=this.material
        this.kk=defs
        this.geometry.toGPU();
        let defGeometry=this.geometry.defs
        let configGeometry=this.geometry.config
        let {vertexBuffer,geometryParams,geometryEntriesGroup,geometrEntriesLayout}=this.geometry
        this.defs={...defs,...defGeometry}
        this.config={...config,...configGeometry}
        if(grouplayouts2) this.grouplayouts2=grouplayouts2
        if(bindGroup2) this.bindGroup2=bindGroup2
        if(grouplayouts3) this.grouplayouts3=grouplayouts3
        if(bindGroup3) this.bindGroup3=bindGroup3
        if(geometryEntriesGroup?.length>0) this.geometryEntriesGroup=geometryEntriesGroup
        if(geometrEntriesLayout?.length>0) this.geometrEntriesLayout=geometrEntriesLayout
        if(vertexBuffer) this.vertexBuffer=vertexBuffer
        if(geometryParams) this.geometryParams=geometryParams
    }
}

export { Mesh }